// done
#include "car.hpp"
// #include "help.hpp"
#include "utils/cmdline.hpp"
#include "utils/logWriter.hpp"
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
#include <map>
#include <unordered_map>
using namespace std;
/**
 * @description: 初始变量
 * @param {
 * L0, L1, V0, V1, Green
 * }
 * @return {*}
 */
double L0 = 100;
double L1 = 20;
double V0 = 8;
double V1 = 0;
bool Green = false;
LogWriter LOG("./app.log");
void praseLine(int argc, char *argv[]);
void init(Car& emergency, Car& team);
void print(Car& emergency, Car& team);
/**
 * @description:全局入口函数 
 * @param {
 * argc：参数个数
 * argv：相关输入参数
 * }
 * @return {int}
 * @src: 
 */
int main(int argc, char *argv[])
{
  // 下面几行用作函数参数解析
  ///////////////////////////
  praseLine(argc, argv);
  ///////////////////////////
  Car emergency;
  Car team;
  init(emergency, team);
  // 初始化相关数据
  initializer(emergency, team);
  if (Green) print(emergency, team);
  // cout << L1 << ' ' << L0 << ' ' << V1 << ' ' << V0 << '\n';
  // cout << emergency.getCurTime_tg() << '\n';
  // cout << emergency.getCurTime_td() << '\n';
  // cout << emergency.getCurTime_t1() << '\n';
  // 当前为绿灯
  if (Green) 
  {
    LOG.write("绿灯剩余时间 %f s", emergency.getCurTime_tg());
    processGreen(emergency, team);
  } 
  // 当前为红灯
  else
  {
    processRed(emergency, team);
  }
  // cin >> L1;
  return 0;
}
/**
 * @description: 初始化速度距离等
 * @param {
 * emergency： 应急车辆
 * team：排队车列
 * }
 * @return {void}
 * @src: 
 */
void init(Car& emergency, Car& team)
{
  // 设置应急车辆距离交叉口的距离  L0
  emergency.setDistance(L0);
  // 设置当前应急车辆的速度 V0
  emergency.setSpeed(V0);
  // 设置排队车列长度  L1
  team.setDistance(L1);
  // 设置排队车列的速度 V1
  team.setSpeed(V1);
}
void print(Car& emergency, Car& team)
{
  cout << "---------------------应急车辆交叉路口车速引导系统---------------------\n\n";
  if (true)
  {
    cout << "应急车辆距离 L0: \t" << L0 << "m\t" << "应急车辆的速度 V0: \t" << V0 << "m/s\n";
    cout << "排队车列长度 L1: \t" << L1 << "m\t" << "排队车列的速度 V1: \t" << V1 << "m/s\n";
    cout << "绿灯剩余时间 tg: \t" << emergency.getCurTime_tg() << "s\n";
    cout << "车列消散时间 td: \t" << emergency.getCurTime_td() << "s\n";
    cout << "发生冲突时间 t1: \t" << emergency.getCurTime_t1() << "s\n";
  }
  cout << "------------------------------------------------------------------------\n\n";
}
/**
 * @description: 基于 cmdline 库解析命令行参数
 * @param {
 * argc, 
 * argv
 * }
 * @return {void}
 */
void praseLine(int argc, char *argv[])
{
  // create a parser
  cmdline::parser a;
    // add specified type of variable.
  // 1st argument is long name
  // 2nd argument is short name (no short name if '\0' specified)
  // 3rd argument is description
  // 4th argument is mandatory (optional. default is false)
  // 5th argument is default value  (optional. it used when mandatory is false)
  a.add<double>("l0", 'l', "emergency distance", false, 100);
  a.add<double>("l1", 'm', "team length", false, 20);
  // 6th argument is extra constraint.
  // Here, port number must be 1 to 20 by cmdline::range().
  a.add<double>("v0", 'v', "emergency velocity v0", false, 8, cmdline::range(1, 20));
  a.add<double>("v1", 'w', "team velocity v1", false, 0, cmdline::range(0, 20));
  a.add<bool>("green", 'g', "Green switch", false, false);
  // Run parser.
  // It returns only if command line arguments are valid.
  // If arguments are invalid, a parser output error msgs then exit program.
  // If help flag ('--help' or '-?') is specified, a parser output usage message then exit program.
  a.parse_check(argc, argv);
  // use flag values
  L0 = a.get<double>("l0");
  L1 = a.get<double>("l1");
  V0 = a.get<double>("v0");
  V1 = a.get<double>("v1");
  Green = a.get<bool>("green");
  cout << L0 << ' ' << L1 << ' ' << V0 << ' ' << ' ' << V1  << ' ';
  cout << boolalpha << Green << '\n';
}